//! Party服务
//! 提供Party实体的基础CRUD操作

use crate::client::EntityClient;
use crate::models::party::*;
use crate::models::view_entities::*;
use crate::models::*;
use crate::services::{QueryBuilder, PagedResult};
use crate::{Result, PartyModError};
use std::collections::HashMap;
use chrono::{DateTime, Utc};

// 为了向后兼容，定义Organization类型别名
use crate::models::party::PartyGroup;
type Organization = PartyGroup;

/// Party服务
#[derive(Clone)]
pub struct PartyService {
    client: EntityClient,
}

impl PartyService {
    /// 创建新的Party服务
    pub fn new(client: EntityClient) -> Self {
        Self { client }
    }

    /// 创建新的Party
    pub async fn create_party(&mut self, party: &Party) -> Result<String> {
        let data_row = party.to_data_row();
        
        self.client.insert_data("Party", data_row).await?;
        Ok(party.party_id.clone())
    }

    /// 根据ID获取Party
    pub async fn get_party(&mut self, party_id: &str) -> Result<Option<Party>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "Party",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        if let Some(row) = response.first() {
            let party = Party::from_data_row(&row.fields)?;
            Ok(Some(party))
        } else {
            Ok(None)
        }
    }

    /// 更新Party
    pub async fn update_party(&mut self, party: &Party) -> Result<()> {
        let data_row = party.to_data_row();
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party.party_id.clone(),
            logic: "AND".to_string(),
        }];
        
        self.client.update_data("Party", data_row, conditions).await?;
        Ok(())
    }

    /// 删除Party
    pub async fn delete_party(&mut self, party_id: &str) -> Result<()> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        self.client.delete_data("Party", conditions).await?;
        Ok(())
    }

    /// 查询Party列表
    pub async fn find_parties(&mut self, query_builder: QueryBuilder) -> Result<Vec<Party>> {
        let query = query_builder.build();
        
        let response = self.client.query_data(
            "Party",
            None,
            Some(query.conditions.into_iter().map(|c| c.into()).collect()),
            query.order_by.first().cloned(),
            query.limit,
            query.offset
        ).await?;
        
        let mut parties = Vec::new();
        for row in response {
            let party = Party::from_data_row(&row.fields)?;
            parties.push(party);
        }
        
        Ok(parties)
    }

    /// 分页查询Party列表
    pub async fn find_parties_paged(
        &mut self, 
        query_builder: QueryBuilder, 
        page: i32, 
        page_size: i32
    ) -> Result<PagedResult<Party>> {
        let offset = (page - 1) * page_size;
        let query_builder = query_builder.limit(page_size).offset(offset);
        
        let parties = self.find_parties(query_builder).await?;
        
        // 注意：这里没有获取总数，实际应用中可能需要额外的查询来获取总数
        Ok(PagedResult::new(parties, None, page_size, page))
    }

    /// 根据类型查询Party
    pub async fn find_parties_by_type(&mut self, party_type: &str) -> Result<Vec<Party>> {
        let query = QueryBuilder::new()
            .eq("partyTypeId", party_type);
        
        self.find_parties(query).await
    }

    /// 根据状态查询Party
    pub async fn find_parties_by_status(&mut self, status_id: &str) -> Result<Vec<Party>> {
        let query = QueryBuilder::new()
            .eq("statusId", status_id);
        
        self.find_parties(query).await
    }

    /// 搜索Party（模糊匹配描述）
    pub async fn search_parties(&mut self, keyword: &str) -> Result<Vec<Party>> {
        let query = QueryBuilder::new()
            .like("description", keyword);
        
        self.find_parties(query).await
    }

    /// 创建个人Party
    pub async fn create_person(&mut self, person: &Person) -> Result<String> {
        // 首先创建Party
        let party = Party {
            party_id: person.party_id.clone(),
            party_type_id: "PERSON".to_string(),
            external_id: None,
            preferred_currency_uom_id: None,
            description: Some(format!("{} {}", 
                person.first_name.as_deref().unwrap_or(""),
                person.last_name.as_deref().unwrap_or("")
            ).trim().to_string()),
            status_id: Some("PARTY_ENABLED".to_string()),
            created_date: Some(Utc::now()),
            created_by_user_login: None,
            last_modified_date: Some(Utc::now()),
            last_modified_by_user_login: None,
            data_source_id: None,
            is_unread: Some(false),
        };
        
        self.create_party(&party).await?;
        
        // 然后创建Person
        let data_row = person.to_data_row();
        
        self.client.insert_data("Person", data_row).await?;
        Ok(person.party_id.clone())
    }

    /// 获取个人信息
    pub async fn get_person(&mut self, party_id: &str) -> Result<Option<Person>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "Person",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        if let Some(row) = response.first() {
            let person = Person::from_data_row(&row.fields)?;
            Ok(Some(person))
        } else {
            Ok(None)
        }
    }

    /// 更新个人信息
    pub async fn update_person(&mut self, person: &Person) -> Result<()> {
        let data_row = person.to_data_row();
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: person.party_id.clone(),
            logic: "AND".to_string(),
        }];
        
        self.client.update_data("Person", data_row, conditions).await?;
        Ok(())
    }

    /// 创建组织Party
    pub async fn create_party_group(&mut self, party_group: &PartyGroup) -> Result<String> {
        // 首先创建Party
        let party = Party {
            party_id: party_group.party_id.clone(),
            party_type_id: "PARTY_GROUP".to_string(),
            external_id: None,
            preferred_currency_uom_id: None,
            description: party_group.group_name.clone(),
            status_id: Some("PARTY_ENABLED".to_string()),
            created_date: Some(Utc::now()),
            created_by_user_login: None,
            last_modified_date: Some(Utc::now()),
            last_modified_by_user_login: None,
            data_source_id: None,
            is_unread: Some(false),
        };
        
        self.create_party(&party).await?;
        
        // 然后创建PartyGroup
        let data_row = party_group.to_data_row();
        
        self.client.insert_data("PartyGroup", data_row).await?;
        Ok(party_group.party_id.clone())
    }

    /// 获取组织信息
    pub async fn get_party_group(&mut self, party_id: &str) -> Result<Option<PartyGroup>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "PartyGroup",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        if let Some(row) = response.first() {
            let party_group = PartyGroup::from_data_row(&row.fields)?;
            Ok(Some(party_group))
        } else {
            Ok(None)
        }
    }

    /// 更新组织信息
    pub async fn update_party_group(&mut self, party_group: &PartyGroup) -> Result<()> {
        let data_row = party_group.to_data_row();
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_group.party_id.clone(),
            logic: "AND".to_string(),
        }];
        
        self.client.update_data("PartyGroup", data_row, conditions).await?;
        Ok(())
    }

    /// 获取Party和Person的组合视图
    pub async fn get_party_and_person(&mut self, party_id: &str) -> Result<Option<PartyAndPerson>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "PartyAndPerson",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        if let Some(row) = response.first() {
            let party_and_person = PartyAndPerson::from_data_row(&row.fields)?;
            Ok(Some(party_and_person))
        } else {
            Ok(None)
        }
    }

    /// 获取Party和Group的组合视图
    pub async fn get_party_and_group(&mut self, party_id: &str) -> Result<Option<PartyAndGroup>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "PartyAndGroup",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        if let Some(row) = response.first() {
            let party_and_group = PartyAndGroup::from_data_row(&row.fields)?;
            Ok(Some(party_and_group))
        } else {
            Ok(None)
        }
    }

    /// 创建Party角色
    pub async fn create_party_role(&mut self, party_role: &PartyRole) -> Result<()> {
        let data_row = party_role.to_data_row();
        
        self.client.insert_data("PartyRole", data_row).await?;
        Ok(())
    }

    /// 获取Party的所有角色
    pub async fn get_party_roles(&mut self, party_id: &str) -> Result<Vec<PartyRole>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "PartyRole",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        let mut roles = Vec::new();
        for row in response {
            let role = PartyRole::from_data_row(&row.fields)?;
            roles.push(role);
        }
        
        Ok(roles)
    }

    /// 检查Party是否有指定角色
    pub async fn has_role(&mut self, party_id: &str, role_type_id: &str) -> Result<bool> {
        let conditions = vec![
            crate::models::QueryCondition {
                field: "partyId".to_string(),
                operator: "=".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            },
            crate::models::QueryCondition {
                field: "roleTypeId".to_string(),
                operator: "=".to_string(),
                value: role_type_id.to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let response = self.client.query_data(
            "PartyRole",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        Ok(!response.is_empty())
    }

    /// 删除Party角色
    pub async fn remove_party_role(&mut self, party_id: &str, role_type_id: &str) -> Result<()> {
        let conditions = vec![
            crate::models::QueryCondition {
                field: "partyId".to_string(),
                operator: "=".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            },
            crate::models::QueryCondition {
                field: "roleTypeId".to_string(),
                operator: "=".to_string(),
                value: role_type_id.to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        self.client.delete_data("PartyRole", conditions).await?;
        Ok(())
    }

    /// 创建组织（Organization的别名方法）
    pub async fn create_organization(&mut self, organization: &Organization) -> Result<String> {
        // 将Organization转换为PartyGroup
        let party_group = PartyGroup {
            party_id: organization.party_id.clone(),
            group_name: organization.group_name.clone(),
            group_name_local: None,
            office_site_name: None,
            annual_revenue: organization.annual_revenue,
            num_employees: organization.num_employees,
            ticker_symbol: organization.ticker_symbol.clone(),
            comments: organization.comments.clone(),
            logo_image_url: None,
        };
        
        self.create_party_group(&party_group).await
    }

    /// 添加联系方式
    pub async fn add_contact_mech(&mut self, party_id: &str, contact_mech: &crate::models::contact::ContactMech) -> Result<()> {
        let data_row = contact_mech.to_data_row();
        self.client.insert_data("ContactMech", data_row).await?;
        
        // 创建PartyContactMech关联 - 使用正确的结构体
        let party_contact_mech = crate::models::contact::PartyContactMech {
            party_id: party_id.to_string(),
            contact_mech_id: contact_mech.contact_mech_id.clone(),
            from_date: Utc::now(),
            thru_date: None,
            role_type_id: None,
            allow_solicitation: Some(true),
            extension: None,
            verified: Some(false),
            comments: None,
            years_with_contact_mech: None,
            months_with_contact_mech: None,
        };
        
        let party_contact_data = party_contact_mech.to_data_row();
        self.client.insert_data("PartyContactMech", party_contact_data).await?;
        Ok(())
    }

    /// 获取Party的联系方式
    pub async fn get_contact_mechs(&mut self, party_id: &str) -> Result<Vec<crate::models::contact::ContactMech>> {
        let conditions = vec![crate::models::QueryCondition {
            field: "partyId".to_string(),
            operator: "=".to_string(),
            value: party_id.to_string(),
            logic: "AND".to_string(),
        }];
        
        let response = self.client.query_data(
            "PartyContactMechDetail",
            None,
            Some(conditions.into_iter().map(|c| c.into()).collect()),
            None,
            None,
            None
        ).await?;
        
        let mut contact_mechs = Vec::new();
        for row in response {
            if let (Some(contact_mech_id), Some(contact_mech_type_id)) = (
                row.fields.get("contactMechId"),
                row.fields.get("contactMechTypeId")
            ) {
                let contact_mech = crate::models::contact::ContactMech {
                    contact_mech_id: contact_mech_id.clone(),
                    contact_mech_type_id: contact_mech_type_id.clone(),
                    info_string: row.fields.get("infoString").cloned(),
                };
                contact_mechs.push(contact_mech);
            }
        }
        
        Ok(contact_mechs)
    }
}